package pine.web.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.LockMode;
import org.hibernate.criterion.Criterion;

import pine.web.common.grid.Pagination;

public interface HibernateDao<T extends Object> {
	
	/**
	 * 增加或更新实体
	 * @param entity
	 * @return
	 */
	public T save(T entity);
	
	/**
	 * 增加或更新集合中的全部实体
	 * @param entities
	 */
	public void saveAll(Collection<T> entities);
	
	/**
	 * 根据主键获取实体，如果没有相应的实体，返回 null
	 * @param id
	 * @return
	 */
	public T get(Serializable id);
	
	/**
	 * 根据主键获取实体并加锁，如果没有相应的实体，返回 null
	 * @param id
	 * @param lock
	 * @return
	 */
	public T getWithLock(Serializable id, LockMode lock);
	
	/**
	 * 持久化指定实体
	 * @param entity
	 * @return
	 */
	public T merge(T entity);
	
	/**
	 * 强制缓存中指定实体与数据库进行同步
	 * @param entity
	 * @return
	 */
	public T evict(T entity);
	
	/**
	 * 根据主键获取实体。如果没有相应的实体，抛出异常
	 * @param id
	 * @return
	 */
	public T load(Serializable id);
	
	/**
	 * 获取全部实体
	 * @return
	 */
	public List<T> loadAll();
	
	/**
	 * 根据主键删除指定实体
	 * 如果id为NULL则不执行任何操作
	 * @param id
	 */
	public void remove(Serializable id);
	
	/**
	 * 删除指定实体
	 * @param t
	 */
	public void remove(T t);
	
	/**
	 * 加锁并删除指定的实体
	 * @param t
	 * @param lockMode
	 */
	public void remove(T t, LockMode lockMode);
	
	/**
	 * 删除集合中的全部实体
	 * @param entities
	 */
	public void removeAll(Collection<T> entities);
	
	/**
	 * 加锁指定实体
	 * @param entity
	 * @param lockMode
	 */
	public void lock(T entity, LockMode lockMode);
	
	/**
	 * 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
	 */
	public void flush();
	
	//-------------------------- Example ---------------------------//
	/**
	 * 根据指定实体中的各种条件取值进行查询
	 * @param t
	 * @return
	 */
	public List<T> findByExample(T t);
	
	/**
	 * 根据指定实体中的各种条件取值进行查询
	 * @param t
	 * @param start
	 * @param limit
	 * @return
	 */
	public List<T> findByExample(T t, Integer start, Integer limit);
	
	//-------------------------- Criteria ---------------------------//
	
	/**
	 * 根据动态查询条件进行查询
	 * @param criterions
	 * @return
	 */
	public List<T> findByCriteria(Criterion... criterions);
	
	/**
	 * 根据动态查询条件进行查询，限定一次查询的数量
	 * @param firstResult
	 * @param maxResults
	 * @param criterions
	 * @return
	 */
	public List<T> findByCriteria(Integer firstResult, Integer maxResults, Criterion... criterions);
	
	/**
	 * 根据动态查找条件查询出记录条数
	 * @param criterions
	 * @return
	 */
	public long countByCriteria(Criterion... criterions);
	
	/**
	 * 根据动态查询条件想找出分页数据
	 * @param page
	 * @param criterions
	 * @return
	 */
	public Pagination<T> findPageByCriteria(Pagination<T> page, Criterion... criterions);
}
